// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "UI/LyraSimulatedInputWidget.h"

#include "LyraJoystickWidget.generated.h"

#define UE_API LYRAGAME_API

class UImage;
class UObject;
struct FGeometry;
struct FPointerEvent;

/**
 *  Lyra虚拟摇杆的UMG包装器。
 *
 *  这将计算一个在-1和1之间钳位的2D向量
 *  作为键值输入给玩家，模拟游戏手柄模拟摇杆。
 *
 *  这旨在与增强输入玩家一起使用。
 */
UCLASS(MinimalAPI, meta=( DisplayName="Lyra Joystick" ))
class ULyraJoystickWidget : public ULyraSimulatedInputWidget
{
	GENERATED_BODY()
	
public:
	
	UE_API ULyraJoystickWidget(const FObjectInitializer& ObjectInitializer); // 构造函数

	//~ Begin UUserWidget
	/**
	 * 触摸开始时的原生处理
	 * @param InGeometry 几何信息
	 * @param InGestureEvent 手势事件
	 * @return 回复
	 */
	UE_API virtual FReply NativeOnTouchStarted(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent) override;
	/**
	 * 触摸移动时的原生处理
	 * @param InGeometry 几何信息
	 * @param InGestureEvent 手势事件
	 * @return 回复
	 */
	UE_API virtual FReply NativeOnTouchMoved(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent) override;
	/**
	 * 触摸结束时的原生处理
	 * @param InGeometry 几何信息
	 * @param InGestureEvent 手势事件
	 * @return 回复
	 */
	UE_API virtual FReply NativeOnTouchEnded(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent) override;
	/**
	 * 鼠标离开时的原生处理
	 * @param InMouseEvent 鼠标事件
	 */
	UE_API virtual void NativeOnMouseLeave(const FPointerEvent& InMouseEvent) override;
	/**
	 * 原生Tick函数
	 * @param MyGeometry 几何信息
	 * @param InDeltaTime 增量时间
	 */
	UE_API virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime) override;
	//~ End UUserWidget interface
	
protected:

	/**
	 * 计算当前触摸从原点的增量位置。
	 *
	 * 在玩家上输入相关的游戏手柄键
	 *
	 * 根据给定的输入移动前景摇杆图像，使其看起来像是
	 * 随着玩家的手指移动
	 */
	UE_API void HandleTouchDelta(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent);
	
	/** 刷新任何已注入的玩家输入并禁用此模拟摇杆的使用。 */
	UE_API void StopInputSimulation();

	/** 摇杆内部图像可以移动多远？ */
	UPROPERTY(BlueprintReadOnly, EditAnywhere) // 摇杆范围
	float StickRange = 50.0f;

	/** 用作摇杆背景的图像 */
	UPROPERTY(BlueprintReadWrite, meta = (BindWidget)) // 摇杆背景图像
	TObjectPtr<UImage> JoystickBackground;

	/** 用作摇杆前景的图像 */
	UPROPERTY(BlueprintReadWrite, meta = (BindWidget)) // 摇杆前景图像
	TObjectPtr<UImage> JoystickForeground;

	/** 我们是否应该否定摇杆的Y轴值？这对于"移动"摇杆很常见 */
	UPROPERTY(BlueprintReadWrite, EditAnywhere) // 是否否定Y轴
	bool bNegateYAxis = false;

	/** 触摸的起源。在 NativeOnTouchStarted 中设置 */
	UPROPERTY(Transient) // 触摸起源
	FVector2D TouchOrigin = FVector2D::ZeroVector;

	UPROPERTY(Transient) // 摇杆向量
	FVector2D StickVector = FVector2D::ZeroVector;
};

#undef UE_API